package com.tanhua.manage.service;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.domain.db.Admin;
import com.tanhua.manage.exception.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AdminService extends ServiceImpl<AdminMapper, Admin> {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    // 验证码的key
    private final String MANAGE_CAP = "MANAGE_CAP_";
    // token的key
    private final String MANAGE_TOKEN = "MANAGE_TOKEN_";
    @Value("${tanhua.secret}")
    private String secret;

    /**
     * 验证码存储到redis
     */
    public void saveCap(String uuid, String code) {
        String key = MANAGE_CAP + uuid;
        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(5));
    }

    public ResponseEntity<Object> login(Map<String, String> map) {
        //1. 获取请求参数：username、password、verificationCode、uuid
        String username = map.get("username");
        String password = map.get("password");
        String verificationCode = map.get("verificationCode");
        String uuid = map.get("uuid");

        //2. 获取redis中的验证码
        String key = MANAGE_CAP+uuid;
        String redisCode = redisTemplate.opsForValue().get(key);

        //3. 验证码校验
        if (StringUtils.isEmpty(redisCode) || !redisCode.equals(verificationCode)) {
            throw new BusinessException("验证码校验失败！");
        }

        //4. 校验成功，删除redis中验证码
        redisTemplate.delete(key);

        //5. 根据用户名查询数据库
        Admin admin = query().eq("username", username).one();

        //6. 校验用户名、密码 [用户输入的密码按照md5加密与数据库密码对比]
        if (admin == null || !admin.getPassword().equals(SecureUtil.md5(password))) {
            throw new BusinessException("用户名或者密码错误！");
        }

        //7. 生成token、存储到redis、返回
        // 定义map
        Map<String,Object> tokenMap = new HashMap<>();
        tokenMap.put("id",admin.getId());
        tokenMap.put("username",admin.getUsername());
        // 生成token
        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, secret).setClaims(tokenMap).compact();
        // 对象转换为json
        String adminJson = JSON.toJSONString(admin);
        // 存储到redis中
        redisTemplate.opsForValue().set(MANAGE_TOKEN+token,adminJson,Duration.ofHours(4));
        // 返回
        Map<String,String> result = new HashMap<>();
        result.put("token",token);
        return ResponseEntity.ok(result);
    }

    /**
     * 根据token登陆用户信息
     * @param token
     * @return
     */
    public Admin findUserByToken(String token) {
        String key = MANAGE_TOKEN + token;
        // 获取redis中的用户的json字符串
        String adminJson = redisTemplate.opsForValue().get(key);
        // 转换为对象
        Admin admin = JSON.parseObject(adminJson, Admin.class);
        // 刷新token有效时间: 重新设置指定的key的有效时间为4个小时
        redisTemplate.expire(key,4, TimeUnit.HOURS);
        return admin;
    }

    /**
     * 接口名称：用户登出
     */
    public ResponseEntity<Object> logout(String token) {
        // 删除redis中的token
        String key = MANAGE_TOKEN + token;
        redisTemplate.delete(key);
        return ResponseEntity.ok(null);
    }
}
